home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
ulib
/
rect.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
6KB
|
270 lines
/***********************************************************************
* $Id: rect.c,v 0.80 1994/02/24 09:48:11 zhao Exp $
*
*. Copyright(c) 1993,1994 by T.C. Zhao
* All rights reserved.
*.
*
* Relationships between rectangles. Any rectangle returned
* must be used right away as the returned stuff is in
* a static buffer (a rotating buffer is actually used).
***********************************************************************/
#if !defined(lint) && defined(F_ID)
char *id_rect = "$Id: rect.c,v 0.80 1994/02/24 09:48:11 zhao Exp $";
#endif
#include "ulib.h"
#define MAX_RECT_BUF 15 /* max. rect buffer. */
/**************************************************************
* Make a rectangle
**************************************************************/
const Rect_t *
make_rect(int x, int y, int w, int h)
{
static Rect_t dummy[MAX_RECT_BUF];
static int nb;
Rect_t *r = dummy + (nb++ % MAX_RECT_BUF);
r->x = x;
r->y = y;
r->w = w;
r->h = h;
return r;
}
/***************************************************************
* rectangle might have a negative width or/and height, canonicalize
* so that width & height are positive
***************************************************************/
Rect_t *
canonicalize_rect(Rect_t *r)
{
if (r->w < 0)
{
r->w = -r->w;
r->x -= r->w;
}
if (r->h < 0)
{
r->h = -r->h;
r->y -= r->h;
}
return r;
}
/***************************************************************
* Test to see if point (x,y) is within rectangle *r
***************************************************************/
int
inside_rect(int x, int y, const Rect_t *rin)
{
Rect_t dummy;
Rect_t *r = &dummy;
canonicalize_rect(copy_rect(r, rin));
return (x >= r->x && x <= r->x + r->w - 1) &&
(y >= r->y && y <= r->y + r->h - 1);
}
int
equal_rect(const Rect_t *r1, const Rect_t *r2)
{
return (r1->x == r2->x && r1->y == r2->y &&
r1->w == r2->w && r1->h == r2->h);
}
void
shift_rect(Rect_t *r, int dx, int dy)
{
r->x += dx;
r->y += dy;
}
void
inc_rect(Rect_t *r, int dx, int dy)
{
r->w += dx;
r->h += dy;
}
void
set_rect(Rect_t *r, int x, int y, int w, int h)
{
r->x = x;
r->y = y;
r->w = w;
r->h = h;
}
Rect_t *
copy_rect(Rect_t *des, const Rect_t *src)
{
des->x = src->x;
des->y = src->y;
des->w = src->w;
des->h = src->h;
return des;
}
/***************************************************************
* Check if two rectangles overlap. If yes, return the union
* else return 0
***************************************************************/
const Rect_t *
union_rect(const Rect_t *r1, const Rect_t *r2)
{
static Rect_t over[MAX_RECT_BUF];
static int nb;
register Rect_t *p = over + (nb++ % MAX_RECT_BUF);
register int xi, yi, xf, yf;
xi = p->x = Max(r1->x, r2->x);
yi = p->y = Max(r1->y, r2->y);
xf = Min(r1->x + r1->w, r2->x + r2->w) - 1;
yf = Min(r1->y + r1->h, r2->y + r2->h) - 1;
p->w = xf - xi + 1;
p->h = yf - yi + 1;
return (p->w > 0 && p->h > 0) ? p : 0;
}
/***************************************************************
* check if r1 contains r2
**************************************************************/
int
cover_rect(const Rect_t *r1, const Rect_t *r2)
{
return (r1->x <= r2->x && r1->y <= r2->y &&
(r1->x + r1->w - 1) >= (r2->x + r2->w - 1) &&
(r1->y + r1->h - 1) >= (r2->y + r2->h - 1));
}
const Rect_t *
sum_rect(const Rect_t *r1, const Rect_t *r2)
{
static Rect_t sr[MAX_RECT_BUF];
static int nb;
register Rect_t *p = sr + (nb++ % MAX_RECT_BUF);
register int xf, yf;
p->x = Min(r1->x, r2->x);
p->y = Min(r1->y, r2->y);
xf = Max(r1->x + r1->w - 1, r2->x + r2->w - 1);
yf = Max(r1->y + r1->h - 1, r2->y + r2->h - 1);
p->w = xf - p->x + 1;
p->h = yf - p->y + 1;
return p;
}
void
print_rect(const char *n, const Rect_t *r)
{
fprintf(stderr, "%s: X=%d Y=%d W=%d H=%d\n",
n, r->x, r->y, r->w, r->h);
}
#if 0
/****************************************************************
* Find all regions that does not overlap with r1
* (r2 U r1) - r1
***************************************************************/
/**** TO BE WRITTEN ****/
Rect_t *
rect_exclude(Rect_t *r1, Rect_t *r2, int *n)
{
static Rect_t reg[4];
int x1f, x2f, y1f, y2f;
register Rect_t *p = reg;
*n = 0;
if (!rect_overlap(r1, r2))
{
*n = 1;
return r2;
}
/* if r1 completely covers r2 */
if (r1->x <= r2->x && r1->y <= r2->y &&
(r1->x + r1->w) >= (r2->x + r2->w) &&
(r1->y + r1->h) >= (r2->y + r2->h))
{
*n = 0;
return 0;
}
/* r2 completely covers r1 */
x1f = r1->x + r1->w - 1;
x2f = r2->x + r2->w - 1;
y1f = r1->y + r1->h - 1;
y2f = r2->y + r2->h - 1;
/* partial overlap. Several cases */
/* horizontal bound */
if (r2->x >= r1->x && x2f <= x1f)
{
if (r2->y >= r1->y)
{ /* upper vertical */
p->x = r2->x;
p->y = y1f + 1;
p->w = r2->w;
p->h = y2f - reg[*n].y;
++p;
++(*n);
}
else if (y2f < y1f)
{ /* lower vertical */
p->x = r2->x;
p->y = r2->y;
p->w = r2->w;
p->h = r1->y - reg[*n].y;
++p;
++(*n);
}
else
{ /* both upper and lower */
p->x = r2->x;
p->y = y1f + 1;
p->w = r2->w;
p->h = y2f - reg[*n].y;
++(*n);
++p;
p->x = r2->x;
p->y = r2->y;
p->w = r2->w;
p->h = r1->y - reg[*n].y;
++(*n);
++p;
}
}
else if (r2->x > r1->x)
{ /* left */
}
else if (r2->x < r1->x)
{ /* right */
}
else
{ /* mixed */
}
return reg;
}
#endif